package com.itheima.Service.impl;

import com.itheima.Service.ReportService;
import com.itheima.common.entity.*;
import com.itheima.dao.MemberDao;
import com.itheima.dao.OrderDao;
import com.itheima.dao.SetmealDao;
import com.itheima.pojo.Order;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Date;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;

@Service
public class ReportServiceImpl implements ReportService {
    @Autowired
    private MemberDao memberDao;
    @Autowired
    private SetmealDao setmealDao;
    @Autowired
    private OrderDao orderDao;
    /**
     * 获取套餐占比统计数据
     * @return
     */
    @Override
    public SetmealReportVO getSetmealReport() {

        List<SetmealCountVO>  setmealCountVOList =setmealDao.getNameCount();

        List<String> setmealNames=new ArrayList<>();
        for (SetmealCountVO setmealCountVO : setmealCountVOList) {
            setmealNames.add(setmealCountVO.getName());
        }
        return new SetmealReportVO(setmealNames,setmealCountVOList);
    }
    /**
     * 获取会员数量统计数据
     * @return
     */
    @Override
    public MemberReportVO getMemberReport() {
        //获取会员前12个月的的每月总人数
        LocalDate localDateNow = LocalDate.now(); //当前时间
        LocalDate beforeMonthEnd = localDateNow.minusDays(localDateNow.getDayOfMonth());//获取上个月的最后一天

        List<String> months=new ArrayList<>();
        List<Integer> memberCounts=new ArrayList<>();
        for (int i = 0; i <12 ; i++) {
            LocalDate localDateMonthEnd = beforeMonthEnd.minusMonths(i); //前推i个月
            Date date=Date.valueOf(localDateMonthEnd);  //每月的最后一天日期
            Integer memberCount= memberDao.getAllCount(date); //统计

            months.add(date.toString().replace("-",".")); //输出格式化
            memberCounts.add(memberCount);
        }

        return new MemberReportVO(months,memberCounts);
    }
    /**
     * 导出运营数据到Excel并提供客户端下载
     * @return
     */
    @Override
    public void exportBusinessReport(HttpServletResponse response) {

        try {
            //获取文件模板的输入流
            InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("templates/report_template.xlsx");
            //获取模板文件的excel对象
            XSSFWorkbook excel=new XSSFWorkbook(inputStream);
            //基于对象获取标签页
            XSSFSheet sheet1 = excel.getSheet("Sheet1");

            //今天日期
            LocalDate todayNow=LocalDate.now();
            //本周的开始时间
            LocalDate startOfWeek = todayNow.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
            //本周的结束时间
            LocalDate endOfWeek = todayNow.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY));
            //本月的开始时间
            LocalDate startOfMonth= todayNow.withDayOfMonth(1);
            //本月的结束时间
            LocalDate endOfMonth= todayNow.withDayOfMonth(todayNow.lengthOfMonth());

            //获取今日新增数,排除空值
            Integer countOfDay= memberDao.getAddCount(todayNow,todayNow);
            //获取近一周新增数,排除空值
            Integer countOfWeek= memberDao.getAddCount(startOfWeek,endOfWeek);
            //获取近一个月新增数,排除空值
            Integer countOfMonth= memberDao.getAddCount(startOfMonth,endOfMonth);
            //获取总会员数,排除空值
            Integer countOfAll= memberDao.getAllCount(Date.valueOf(todayNow));

            //运营数据统计
            //获取并设置第3行6列,日期
            sheet1.getRow(2).getCell(5).setCellValue(String.valueOf(todayNow));
            //会员数据统计
            //获取并设置第5行6列,新增会员数
            sheet1.getRow(4).getCell(5).setCellValue(countOfDay);
            //获取并设置第5行7列,总会员数
            sheet1.getRow(4).getCell(7).setCellValue(countOfAll);
            //获取并设置第6行6列,本周新增会员数
            sheet1.getRow(5).getCell(5).setCellValue(countOfWeek);
            //获取并设置第6行7列,本月新增会员数
            sheet1.getRow(5).getCell(7).setCellValue(countOfMonth);

            //预约到诊数据统计
            //获取并设置第8行6列,今日预约数
            Integer orderCountOfDay= orderDao.getOrderCount(todayNow,todayNow,null);
            sheet1.getRow(7).getCell(5).setCellValue(orderCountOfDay);
            //获取并设置第8行7列,今日到诊数
            Integer ArriveOfDay= orderDao.getOrderCount(todayNow,todayNow,Order.ORDERSTATUS_YES);
            sheet1.getRow(7).getCell(7).setCellValue(orderCountOfDay);
            //获取并设置第9行6列,本周预约数
            Integer orderCountOfWeek= orderDao.getOrderCount(startOfWeek,endOfWeek,null);
            sheet1.getRow(8).getCell(5).setCellValue(orderCountOfDay);
            //获取并设置第9行7列,本周到诊数
            Integer ArriveOfWeek= orderDao.getOrderCount(startOfWeek,endOfWeek,Order.ORDERSTATUS_YES);
            sheet1.getRow(8).getCell(7).setCellValue(orderCountOfDay);
            //获取并设置第10行6列,本月预约数
            Integer orderCountOfMonth= orderDao.getOrderCount(startOfMonth,endOfMonth,null);
            sheet1.getRow(9).getCell(5).setCellValue(orderCountOfDay);
            //获取并设置第10行7列,本月到诊数
            Integer ArriveOfMonth= orderDao.getOrderCount(startOfMonth,endOfMonth,Order.ORDERSTATUS_YES);
            sheet1.getRow(9).getCell(7).setCellValue(orderCountOfDay);

            //热门套餐（前四）
            //获取套餐名称，预约数量，备注,并倒序排
            List<SetmealCountVO2> list= setmealDao.getNameCount2();
            Integer countAll=0;
            for (SetmealCountVO2 setmealCountVO2 : list) {
                countAll = countAll + setmealCountVO2.getValue();
            }
            for (int i = 0; i < 4; i++) {
                //套餐名称
                sheet1.getRow(12+i).getCell(4).setCellValue(list.get(i).getName());
                //预约数量
                sheet1.getRow(12+i).getCell(5).setCellValue(list.get(i).getValue());
                //占比
                double rate= (list.get(i).getValue()) / (countAll * 1.0);
                sheet1.getRow(12+i).getCell(6).setCellValue(rate);
                //备注
                sheet1.getRow(12+i).getCell(7).setCellValue(list.get(i).getRemark());
            }

            //通过输出流将文件下载到客户端浏览器中
            //创建输出流对象
            ServletOutputStream outputStream = response.getOutputStream();
            //执行excel写入
            excel.write(outputStream);
            //关闭资源
            outputStream.flush();
            outputStream.close();
            excel.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 获取运营统计数据
     * @return
     */
    @Override
    public OperationalDataVO getBusinessReportData() {
        //今天日期
        LocalDate todayNow=LocalDate.now();
        //本周的开始时间
        LocalDate startOfWeek = todayNow.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
        //本周的结束时间
        LocalDate endOfWeek = todayNow.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY));
        //本月的开始时间
        LocalDate startOfMonth= todayNow.withDayOfMonth(1);
        //本月的结束时间
        LocalDate endOfMonth= todayNow.withDayOfMonth(todayNow.lengthOfMonth());

        //获取今日新增数,排除空值
        Integer memberCountOfDay= memberDao.getAddCount(todayNow,todayNow);
        //获取近一周新增数,排除空值
        Integer memberCountOfWeek= memberDao.getAddCount(startOfWeek,endOfWeek);
        //获取近一个月新增数,排除空值
        Integer memberCountOfMonth= memberDao.getAddCount(startOfMonth,endOfMonth);
        //获取总会员数,排除空值
        Integer memberCountOfAll= memberDao.getAllCount(Date.valueOf(todayNow));

        //预约到诊数据统计
        //获取,今日预约数
        Integer orderCountOfDay= orderDao.getOrderCount(todayNow,todayNow,null);
        //获取,今日到诊数
        Integer arriveOfDay= orderDao.getOrderCount(todayNow,todayNow,Order.ORDERSTATUS_YES);
        //获取,本周预约数
        Integer orderCountOfWeek= orderDao.getOrderCount(startOfWeek,endOfWeek,null);
        //获取,本周到诊数
        Integer arriveOfWeek= orderDao.getOrderCount(startOfWeek,endOfWeek,Order.ORDERSTATUS_YES);
        //获取,本月预约数
        Integer orderCountOfMonth= orderDao.getOrderCount(startOfMonth,endOfMonth,null);
        //获取,本月到诊数
        Integer arriveOfMonth= orderDao.getOrderCount(startOfMonth,endOfMonth,Order.ORDERSTATUS_YES);

        //热门套餐（前四）
        //获取套餐名称，预约数量，备注,并倒序排
        List<SetmealCountVO2> list= setmealDao.getNameCount2();
        //初始化总预约数
        Integer countAll=0;
        for (SetmealCountVO2 setmealCountVO2 : list) {
            countAll = countAll + setmealCountVO2.getValue();
        }
        List<SetmealOperationalVO> setmealOperationalVOList=new ArrayList<>();
        //热门套餐前四名
        for (int i = 0; i < 4; i++) {
            //占比
            double rate= (list.get(i).getValue()) / (countAll * 1.0);
            //新建对象占比,套餐名称,预约数量
            setmealOperationalVOList.add(new SetmealOperationalVO(rate,
                                                                  list.get(i).getName(),
                                                                  list.get(i).getValue()
                                                                  ));
        }

        return new OperationalDataVO(
                                    todayNow.toString(),
                                    memberCountOfDay,
                                    memberCountOfAll,
                                    memberCountOfWeek,
                                    memberCountOfMonth,
                                    orderCountOfDay,
                                    arriveOfDay,
                                    orderCountOfWeek,
                                    arriveOfWeek,
                                    orderCountOfMonth,
                                    arriveOfMonth,
                                    setmealOperationalVOList);

    }
}
